<?php

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 * Description of BUIScreenFlow
 *
 * @author jianfeng
 */
class BUIScreenFlow extends BUIBase implements Iterator {

    const NEXT = "next";
    const FIRST = "first";
    const PREVIOUS = "previous";
    const LAST = 'last';
    const TRANSITVARIABLE_SCREENFLOW_INDEX = 'screenFlowIndex';

    protected $flow = null;
    protected $index = 0;
    protected $screens = array();
    protected $nextIndex = null;
    protected $previousIndex = null;
    protected $firstIndex = 0;
    protected $lastIndex = null;
    protected $name = null;
    protected $menus = null;
    protected $currentScreen = null;
    protected $uiNode = null;
    public $transitScopeName = 'ScreenFlow';
    private $isMenuRendered = false;
    private $isContentRendered = false;

    public function __construct($name, $parent = NULL) {

        parent::__construct();

        //$path = "application.application.ui.screenflow." . $name;
        $path = Blyn::app()->getActiveServiceApp()->getAppConfig()->screenFlowPath . "." . $name;
        $this->flow = require(Yii::getPathOfAlias($path) . ".php");
        $this->parseScreenFlow($this->flow);

        //$scopeId = 'ScreenFlow_' . str_replace(" ", "_", $this->getName());
        //$this->resetTransitVariables($scopeId, $this->transitScopeName);
    }

    public function setUINode($uiNode) {
        $this->uiNode = $uiNode;
        //$this->resetScreenFlowOnSwitchUINode($uiNode);
        $scopeId = str_replace(" ", "_", $this->getName());
        $parentScopeId = $uiNode->transitScopeName . '_' . $uiNode->getId();
        $this->resetTransitVariables($scopeId, $this->transitScopeName, $parentScopeId);
    }

    public function getUINode() {
        return $this->uiNode;
    }

    protected function parseScreenFlow($flow) {
        $this->screens = $flow['screens'];
        $this->lastIndex = count($this->screens) - 1;
        $this->name = $flow['name'];
        $this->menus = $flow['menus'];
    }

    public function renderMenu($data = null, $style = null) {

        if ($_POST != NULL)
            $this->isMenuRendered = !$this->isMenuRendered;

        if (!$this->isMenuRendered) {
            foreach ($this->menus as $menuname => $menu) {
                if (isset($menu['visible']) && $menu['visible']) {
                    $this->showMenu($menuname, $menu, $data, $style);
                }
            }
        }
    }

    protected function showMenu($menuName, $menu = null, $data = null) {

        if (!is_array($data))
            $data = array();

        $percent = round(($this->index + 1) / ($this->lastIndex + 1) * 100);
        $data['percent'] = $percent;

        $viewName = 'screenflow_' . $menuName;
        $viewName = strtolower($viewName);
        $controller = yii::app()->getController();
        $controller->renderPartial($viewName, $data);
    }

    public function renderContent($data) {

        //   if ($_POST != NULL)
        // $this->isContentRendered = !$this->isContentRendered;
        if (!$this->isContentRendered) {

            if (!is_array($data))
                $data = array();

            //$config['renderType'] = 'renderPartial';

            $this->currentScreen->render($data);
        }
    }

    public function render($data = null) {
        $this->gotoScreenByIndex($this->index, $data);
    }

    public function gotoScreenByIndex($index = 0, $data = null) {

        if ($index < 0 || $index > $this->lastIndex)
            return false;

        $this->index = $index;
        $this->currentScreen = $this->getScreenByIndex($this->index);

        $controller = Yii::app()->getController();

        if (!is_array($data))
            $data = array();

        $data['screenflow'] = $this;

        //$this->onBeforeRenderScreenFlow(new CEvent($this));

        $this->addTransitVariable(self::TRANSITVARIABLE_SCREENFLOW_INDEX, $this->index);

        $controller->renderPartial('screenflow', array('flow' => $this, 'index' => $this->index, 'data' => $data));
    }

    public function getTitle() {
        
    }

    public function getName() {
        return $this->name;
    }

    public function setIndex($index) {
        $this->index = $index;
    }

    public function getIndex() {
        return $this->index;
    }

    public function getScreenByIndex($index) {
        $screen = null;

        if (isset($this->screens[$index])) {
            $screenConfig = $this->screens[$index];
            if (isset($screenConfig['class']))
                $screenClass = $screenConfig['class'];
            else
                $screenClass = 'BScreen' . $screenConfig['name'];

            $screen = new $screenClass();
            $screen->setParent($this);

            return $screen;
        }

        return FALSE;
    }

    public function gotoScreen($name, $data = NULL) {
        if ($name == self::NEXT) {
            $this->next();
            $this->gotoScreenByIndex($this->index, $data);
            return;
        }

        if ($name == self::PREVIOUS) {
            $this->previous();
            $this->gotoScreenByIndex($this->index, $data);
            return;
        }

        if ($name == self::FIRST) {
            $this->index = 0;
            $this->gotoScreenByIndex($this->index, $data);
            return;
        }

        if ($name == self::LAST) {
            $this->index = $this->lastIndex;
            $this->gotoScreenByIndex($this->index, $data);
            return;
        }

        $this->index = $this->getIndexByName($name);
        return $this->gotoScreenByIndex($this->index, $data);
    }

    public function getIndexByName($name) {
        $i = 0;
        foreach ($this->screens as $screen) {
            $screenClass = isset($screen['class']) ? $screen['class'] : 'no-class';
            $screenName = 'BScreen' . $screen['name'];
            if ($name == $screenName || $name == $screenClass)
                return $i;
            $i++;
        }
        return -1;
    }

    public function getScreenByName($name) {
        if ($name == self::NEXT) {
            $this->index++;
            return $this->current();
        }

        if ($name == self::PREVIOUS) {
            $this->index--;
            return $this->current();
        }

        if ($name == self::FIRST) {
            $this->index = 0;
            return $this->current();
        }

        if ($name == self::LAST) {
            $this->index = $this->lastIndex;
            return $this->current();
        }

        $this->index = $this->getIndexByName($name);

        if ($this->index < 0 || $this->index > $this->lastIndex)
            return false;
        else
            return $this->current();
    }

    public function current() {
        $screen = $this->screens[$this->index];
        $screen->setParent($this);
        return $screen;
    }

    public function key() {
        return $this->index;
    }

    public function next() {
        ++$this->index;
    }

    public function previous() {
        --$this->index;
    }

    public function rewind() {
        $this->index = 0;
    }

    public function valid() {
        return isset($this->screens[$this->index]);
    }

    public function addTransitVariable($name, $value, $scope = NULL, $type = NULL) {
        if ($scope == NULL)
            $scope = str_replace(" ", "_", $this->getName());

        $scope = 'ScreenFlow_' . $scope;

        parent::addTransitVariable($name, $value, $scope, $type);
    }

    public function getTransitVariable($name, $scope = NULL, $type = NULL) {
        if ($scope == NULL)
            $scope = str_replace(" ", "_", $this->getName());

        $scope = 'ScreenFlow_' . $scope;

        $value = parent::getTransitVariable($name, $scope, $type);
        return $value;
    }

    protected function resetScreenFlowOnSwitchUINode($uiNode) {

        $userId = Blyn::app()->getCurrentUser()->getId();

        $savedUINodeId = $uiNode->getTransitVariable('current_' . $uiNode->transitScopeName);

        $currentUiNodeId = 'u' . $userId . '_' . $uiNode->getId();

        $scope = str_replace(" ", "_", $this->getName());

        if ($savedUINodeId != $currentUiNodeId) {
            $this->resetTransitVariables($scope, $this->transitScopeName);
        }
    }

    protected function registerMenu($event) {
        
    }

}

?>
